home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / xgopher.1.3 / jobs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-20  |  5.1 KB  |  268 lines

  1. /* jobs.c
  2.    get some idea of the jobs spawned by Xgopher */
  3.  
  4.      /*---------------------------------------------------------------*/
  5.      /* Xgopher        version 1.3     08 April 1993                  */
  6.      /*                version 1.2     20 November 1992               */
  7.      /*                version 1.1     20 April 1992                  */
  8.      /*                version 1.0     04 March 1992                  */
  9.      /* X window system client for the University of Minnesota        */
  10.      /*                                Internet Gopher System.        */
  11.      /* Allan Tuchman, University of Illinois at Urbana-Champaign     */
  12.      /*                Computing and Communications Services Office   */
  13.      /* Copyright 1992, 1993 by                                       */
  14.      /*           the Board of Trustees of the University of Illinois */
  15.      /* Permission is granted to freely copy and redistribute this    */
  16.      /* software with the copyright notice intact.                    */
  17.      /*---------------------------------------------------------------*/
  18.  
  19.  
  20. #include <stdio.h>
  21.  
  22. #include "conf.h"
  23. #include "gopher.h"
  24. #include "osdep.h"
  25. #include "jobs.h"
  26.  
  27. #include <sys/wait.h>
  28. #include <sys/time.h>
  29. #ifndef ISCX
  30. #include <sys/resource.h>
  31. #endif
  32.  
  33. static jobList *jobs = (jobList *) NULL;
  34.  
  35.  
  36. /* addJob
  37.    add the given pid to the internal job data structures */
  38.  
  39. void
  40. addJob(t, pid)
  41. char        t;
  42. PID_TYPE    pid;
  43. {
  44.     jobList    *j=(jobList *) malloc(sizeof(jobList));
  45.  
  46.     j->jobType = t;
  47.     j->pid       = pid;
  48.     j->next    = jobs;
  49.  
  50.     jobs = j;
  51.  
  52. }
  53.  
  54.  
  55. /* removeJob
  56.    remove the given pid from the internal job data structures */
  57.  
  58. BOOLEAN
  59. removeJob(pid)
  60. PID_TYPE    pid;
  61. {
  62.     jobList *j, *jp;
  63.  
  64.     jp = NULL;
  65.     for (j=jobs; (j != (jobList *) NULL  &&  j->pid != pid); j=j->next){
  66.         jp = j;
  67.     }
  68.  
  69.     if (j != NULL) {        /* pid in list */
  70. #ifdef DEBUG
  71.         fprintf (stderr, "Remove process %d (type %c)\n",
  72.                 j->pid, j->jobType);
  73. #endif    /* DEBUG */
  74.         if (jp == NULL) {    /* first element */
  75.             jobs = j->next;
  76.         } else {
  77.             jp->next = j->next;
  78.         }
  79.         free(j);
  80.         return TRUE;
  81.     } else {
  82.         return FALSE;
  83.     }
  84. }
  85.  
  86.  
  87. /* findJobPID
  88.    return the item type of the child with the supplied pid */
  89.  
  90. char    
  91. findJobPID(pid)
  92. PID_TYPE    pid;
  93. {
  94.     jobList *j;
  95.  
  96.     for (j=jobs; (j != (jobList *) NULL  &&  j->pid != pid); j=j->next){
  97.     }
  98.  
  99.     return (j == NULL) ? NO_TYPE : j->jobType;
  100. }
  101.  
  102.  
  103. /* findJobType
  104.    return the pid of the first child that matches the supplied type */
  105.  
  106. PID_TYPE
  107. findJobType(t)
  108. char        t;
  109. {
  110.     jobList *j;
  111.  
  112.     for (j=jobs; (j != (jobList *) NULL  &&  j->jobType != t); j=j->next){
  113.     }
  114.  
  115.     return (j == NULL ? NO_JOB: j->pid);
  116. }
  117.  
  118.  
  119. /* killItemProcess
  120.    terminate a specific child process */
  121.  
  122. void
  123. killItemProcess(pid)
  124. PID_TYPE    pid;
  125. {
  126. #ifdef DEBUG
  127.     fprintf (stderr, "killing process %d\n", pid);
  128. #endif    /* DEBUG */
  129.     kill(pid, KILL_SIGNAL);
  130.     waitOnChildren();
  131. }
  132.  
  133.  
  134. /* killAllItemType
  135.    terminate all items that match the supplied type */
  136.  
  137. void
  138. killAllItemType(t)
  139. char        t;
  140. {
  141.     jobList *j;
  142.  
  143. #ifdef DEBUG
  144.     listJobs();
  145.     fprintf (stderr, "killing processes for item type %c\n", t);
  146. #endif    /*  DEBUG */
  147.  
  148.     for (j=jobs; j != (jobList *) NULL; j=j->next){
  149.         if (j->jobType == t) {
  150.             killItemProcess(j->pid);
  151.         }
  152.     }
  153.  
  154. }
  155.  
  156.  
  157. /* killAllItemProcesses
  158.    terminate all child processes. */
  159.  
  160. void
  161. killAllItemProcesses()
  162. {
  163.     jobList *j;
  164.  
  165.     for (j=jobs; j != (jobList *) NULL; j=j->next){
  166.         killItemProcess(j->pid);
  167.     }
  168. }
  169.  
  170.  
  171. /* waitForJob
  172.    block until a specified job is completed */
  173.  
  174. void
  175. waitForJob(waitPID)
  176. PID_TYPE    waitPID;
  177. {
  178.     PID_TYPE    donePID;
  179. #if        !defined(SYSV) && !defined(__convex__) && !defined(__bsdi__) || defined(sgi) && !defined(linux)
  180.     union wait    status;
  181. #else
  182.     int        status;
  183. #endif    /* !defined(SYSV) */
  184.  
  185.     do {
  186.         donePID = wait(&status);
  187. #ifdef        DEBUG
  188.         fprintf (stderr, "Process %d is done\n", donePID);
  189. #endif        /*  DEBUG */
  190.         if (donePID != (PID_TYPE) 0) {
  191.             removeJob(donePID);
  192.         }
  193.  
  194.     } while (donePID != waitPID);
  195. }
  196.  
  197.  
  198. /* childIsGone
  199.    handle signal noting the termination of a child process */
  200.  
  201. void
  202. childIsGone()
  203. {
  204.     waitOnChildren();
  205. }
  206.  
  207.  
  208. /* waitOnChildren
  209.    handle request or signal noting the termination of a child process */
  210.  
  211. void
  212. waitOnChildren()
  213. {
  214.     PID_TYPE    donePID;
  215.  
  216. #if        !defined(SYSV) && !defined(__convex__) && !defined(__bsdi__) || defined(sgi) && !defined(linux)
  217.     union wait    status;
  218. #else
  219.     int        status;
  220. #endif    /* !defined(SYSV) */
  221.  
  222. #if    !defined(macII) && !defined(CRAY) && !defined(SVR4) && !defined(SYSV)
  223. #define WAIT3
  224.     struct rusage    rusage;
  225. #endif    /* MacII, CRAY, SVR4, SYSV */
  226.  
  227.     
  228.     do {
  229.  
  230. #if        defined(macII)
  231.         donePID = wait3(&status, WNOHANG, NULL);
  232. #else        /* not macII */
  233. #  if        !defined(WAIT3)
  234.         donePID = waitpid(-1, &status, WNOHANG);
  235. #  else        /* use wait3 call for others */
  236.         donePID = wait3(&status, WNOHANG, &rusage);
  237. #  endif    /* other */
  238. #endif        /* */
  239.  
  240.         
  241. #ifdef DEBUG
  242.         fprintf (stderr, "Process %d is done\n", donePID);
  243. #endif    /*  DEBUG */
  244.         if (donePID != (PID_TYPE) 0) {
  245.             removeJob(donePID);
  246.         }
  247.  
  248.     } while (donePID > (PID_TYPE) 0);
  249. }
  250.  
  251.  
  252. #ifdef DEBUG
  253. void
  254. listJobs()
  255. {
  256.     jobList *j;
  257.  
  258.     fprintf (stderr, "Active processes started by Xgopher\n");
  259.  
  260.     for (j=jobs; j != (jobList *) NULL; j=j->next){
  261.         fprintf (stderr, "    pid: %6d    Xgopher item type \'%c\'\n",
  262.                 j->pid, j->jobType);
  263.     }
  264.  
  265.     fprintf (stderr, "End of active process list\n");
  266. }
  267. #endif
  268.